// custom-tab-bar/index.js
const App = getApp();
Component({
  lifetimes: {
    attached() {
      this.init(); //初始化是否打开蓝牙
      // 通知父组件 tab 已更改
      this.triggerEvent('changeTab', {
        value: 'home'
      });
    },
  },
  properties: {
    selected: {
      type: String,
      value: 'home'
    }
  },
  data: {
    value: 'home',
    list: [{
      value: 'home',
      icon: '/assets/bottom/bottom_bar_home_icon_selected.png',
      text: '首页'
    },
    {
      value: 'pillow',
      icon: '/assets/bottom/Subtract.png',
      text: '枕头设置'
    },
    {
      value: 'sleep',
      icon: '/assets/bottom/sleepIcon.png',
      text: '睡眠状态'
    },
    {
      value: 'profile',
      icon: '/assets/bottom/myIcon.png',
      text: '我的'
    },
    ],
    iconMap: {
      home: {
        home: '/assets/bottom/bottom_bar_home_icon_selected.png',
        pillow: '/assets/bottom/Subtract.png',
        sleep: '/assets/bottom/sleepIcon.png',
        profile: '/assets/bottom/myIcon.png',
        myProfile: '/assets/bottom/myIcon.png',
      },
      pillow: {
        home: '/assets/bottom/indexLogo.png',
        pillow: '/assets/bottom/bottom_bar_pillow_settings_icon_selected.png',
        sleep: '/assets/bottom/sleepIcon.png',
        profile: '/assets/bottom/myIcon.png',
        myProfile: '/assets/bottom/myIcon.png',
      },
      sleep: {
        home: '/assets/bottom/indexLogo.png',
        pillow: '/assets/bottom/Subtract.png',
        sleep: '/assets/bottom/bottom_bar_sleep_status_icon_selected.png',
        profile: '/assets/bottom/myIcon.png',
        myProfile: '/assets/bottom/myIcon.png',
      },
      profile: {
        home: '/assets/bottom/indexLogo.png',
        pillow: '/assets/bottom/Subtract.png',
        sleep: '/assets/bottom/sleepIcon.png',
        profile: '/assets/bottom/bottom_bar_my_profile_icon_selected.png',
        myProfile: '/assets/bottom/bottom_bar_my_profile_icon_selected.png',
      }
    },

    devices: [],
    popupDev: false,
    connected: false,
    chs: [],
    homeList: null,
    isBluetoothStatus: false,
    confirmBtn: {
      content: '知道了',
      variant: 'base'
    },
  },

  methods: {
    init() {
      wx.getLocation({
        type: 'gcj02',
        success(res) {
          console.log(res)
        }
      })
      this.openBluetoothAdapter();
      // debugger
      // this.setData({
      //   studyType:true,
      //   studyCon:'未检测到您的仰卧数据，请仰卧，并保持5秒'
      // })
    },
    closeDialog() {
      this.setData({
        studyType: false,
      })
    },
    postureFn() {
      let item = {
        currentTarget: {
          dataset: {
            value: 'pillow',
          }
        }
      }
      this.onChange(item);
    },
    myProfileFn() {
      let item = {
        currentTarget: {
          dataset: {
            value: 'myProfile',
          }
        }
      }
      this.onChange(item);
    },
    pillowSetFn() {
      let item = {
        currentTarget: {
          dataset: {
            value: 'pillow',
          }
        }
      }
      this.onChange(item);
      const child = this.selectComponent('#pillow')
      if (child) {
        child.pillowSetFn();
      }
    },
    profileSetFn() {
      let item = {
        currentTarget: {
          dataset: {
            value: 'profile',
          }
        }
      }
      this.onChange(item);
    },
    comforYwFn(setCon) {
      let {
        detail
      } = setCon.detail;
      this.writeBLECharacteristicValue(detail);
    },
    comforCwFn(setCon) {
      let {
        detail
      } = setCon.detail;
      this.writeBLECharacteristicValue(detail);
      wx.showToast({
        title: '设置成功',
        icon: 'none'
      })
    },
    alertSetFn(setCon) {
      let {
        detail
      } = setCon.detail;
      this.writeBLECharacteristicValue(detail);
      wx.showToast({
        title: '设置成功',
        icon: 'none'
      })
    },
    /* 初始化蓝牙模块 */
    openBluetoothAdapter() {
      // 先关闭蓝牙模块再开启 防止断开后点连接连接不上
      this.closeBluetoothAdapter();
      wx.openBluetoothAdapter({
        success: response => {
          console.log("初始化蓝牙模块成功：openBluetoothAdapter", response);
          this.startBluetoothDevicesDiscovery();
        },
        fail: err => {
          if (err.errCode === 10001) {
            /* 监听蓝牙适配器状态变化事件 */
            wx.onBluetoothAdapterStateChange(res => {
              console.log("监听蓝牙适配器状态变化事件：onBluetoothAdapterStateChange", res);
              res.available && this.startBluetoothDevicesDiscovery();
            });
          }
        },
      });
    },
    /* 获取本机蓝牙适配器状态 */
    getBluetoothAdapterState() {
      wx.getBluetoothAdapterState({
        success: res => {
          console.log("getBluetoothAdapterState", res);
          if (res.discovering) {
            // 是否正在搜索设备
            this.onBluetoothDeviceFound();
          } else if (res.available) {
            // 蓝牙适配器是否可用
            this.startBluetoothDevicesDiscovery();
          }
        },
      });
    },
    /* 开始搜寻附近的蓝牙外围设备 */
    startBluetoothDevicesDiscovery() {
      // 开始扫描参数
      if (this._discoveryStarted) return;

      this._discoveryStarted = true;
      wx.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: true,
        success: response => {
          console.log("开始搜寻附近的蓝牙外围设备：startBluetoothDevicesDiscovery", response);
          this.onBluetoothDeviceFound();
        },
        fail: err => {
          console.log("搜索设备失败", err);
          wx.showToast({
            title: "搜索设备失败",
            icon: "none"
          });
        },
      });
    },
    /* 停止搜寻附近的蓝牙外围设备。*/
    stopBluetoothDevicesDiscovery() {
      console.log("停止搜寻附近的蓝牙外围设备");
      wx.stopBluetoothDevicesDiscovery();
    },
    /* 监听搜索到新设备的事件 */
    onBluetoothDeviceFound() {
      let flagType = false;
      wx.onBluetoothDeviceFound(res => {
        let ymDevices = res.devices.filter(device => {
          // 严格匹配 XKL- 开头的设备名称
          // return device?.localName?.startsWith('RED');
          return device?.localName?.startsWith('XKL-');
        });
        if (ymDevices.length > 1) {
          this.setData({
            devices: ymDevices, // 更新数据驱动视图
            popupDev: true,
          });
        } else if (ymDevices.length == 1) {
          this.createBLEConnection(ymDevices[0]);
        } else {
          if (!flagType) {
            flagType = true;
            wx.showToast({
              title: '没有找到蓝牙设备',
              icon: 'none'
            })
          }
        }
      });
    },
    selectDevice(e) {
      let {
        item
      } = e.currentTarget.dataset;
      this.createBLEConnection(item);
      this.setData({
        popupDev: false,
      })
    },
    // 调整mtu大小
    async getMaxBLEMTU(deviceId, mtu, type) {
      try {
        await wx.setBLEMTU({
          deviceId: deviceId,
          mtu: mtu,
        });
        // 如果上一次错误，获取成功后直接返回结果
        if (type === 'error') {
          return mtu;
        } else {
          return getMaxBLEMTU(deviceId, mtu + 20, 'success');
        }
      } catch (error) {
        // 如果是 success 则返回上次成功沟通的值
        if (type === 'success') {
          return mtu - 20;
        } else if (mtu <= 20) {
          return 20;
        }
        return getMaxBLEMTU(deviceId, mtu - 20, 'error');
      }
    },
    /* 连接蓝牙低功耗设备。*/
    createBLEConnection(ds) {
      const deviceId = ds.deviceId;
      const name = ds.name;
      wx.createBLEConnection({
        deviceId,
        success: () => {
          this.setData({
            connected: true,
            name,
            deviceId
          });
          this.setData({
            isBluetoothStatus: true,
          })
          this.localDevices(ds, ds.localName);
          this.getMaxBLEMTU(deviceId, 100);
          wx.showToast({
            title: "连接蓝牙设备成功",
            icon: "none"
          });
          this.getBLEDeviceServices(deviceId);
        },
        fail: e => {
          console.log("连接失败", e.errMsg);
          wx.showToast({
            title: "连接失败,错误信息: " + e.errMsg,
            icon: "none"
          });
        },
      });
      // 停止搜寻蓝牙设备
      this.stopBluetoothDevicesDiscovery();
    },
    //储存成功连接过蓝牙的设备和当前正在连接的设备
    localDevices(device, currentDev) {
      // 存储当前设备
      wx.setStorageSync('currentDev', currentDev);
      // 获取历史设备列表
      const historyDevices = wx.getStorageSync('devices') || [];
      // 根据localName去重
      const exists = historyDevices.some(item =>
        item.localName === device.localName
      );
      if (!exists) {
        // 新增设备并更新存储
        wx.setStorageSync('devices', [...historyDevices, device]);
      }
    },
    /* 断开与蓝牙低功耗设备的连接。 */
    closeBLEConnection() {
      console.log("断开与蓝牙低功耗设备的连接");
      wx.showToast({
        title: "已断开和蓝牙设备的连接",
        icon: "none"
      });
      wx.closeBLEConnection({
        deviceId: this.data.deviceId
      });
      this.setData({
        connected: false,
        chs: [],
        canWrite: false
      });
    },
    /* 获取蓝牙低功耗设备所有服务 (service) */
    getBLEDeviceServices(deviceId) {
      wx.getBLEDeviceServices({
        deviceId,
        success: res => {
          // 遍历所有服务
          for (let i = 0; i < res.services.length; i++) {
            const service = res.services[i];

            // 检查服务是否为主要服务，并且 UUID 以 AA 开头
            if (service.isPrimary && service.uuid && service.uuid.startsWith('AA')) {
              // 调用获取特征值方法
              this.getBLEDeviceCharacteristics(deviceId, service.uuid);
              // 如果只需要第一个匹配的服务，可以添加 break;
              // break;
            }
          }
        },
        fail: err => {
          console.error('获取设备服务失败:', err);
        }
      });
    },
    /* 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)。 */
    getBLEDeviceCharacteristics(deviceId, serviceId) {
      wx.getBLEDeviceCharacteristics({
        deviceId,
        serviceId,
        success: res => {
          for (let i = 0; i < res.characteristics.length; i++) {
            let item = res.characteristics[i];
            if (item.properties.read) {
              wx.readBLECharacteristicValue({
                deviceId,
                serviceId,
                characteristicId: item.uuid,
              });
            }
            if (item.properties.write) {
              this.setData({
                canWrite: true
              });
              this._deviceId = deviceId;
              this._serviceId = serviceId;
              this._characteristicId = item.uuid;
              let characteristic = {
                deviceId,
                serviceId,
                characteristicId: item.uuid
              }
              this.setData({
                characteristic
              })
              //默认发送当前时间
              const now = new Date()
              const timeStr = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}${now.getSeconds().toString().padStart(2, '0')}`;
              this.writeBLECharacteristicValue(`SET:00;${timeStr};00;@`)
              //发送数据 查询主页电量等信息
              this.writeBLECharacteristicValue("RED:01;@");
            }
            if (item.properties.notify || item.properties.indicate) {
              wx.notifyBLECharacteristicValueChange({
                deviceId,
                serviceId,
                characteristicId: item.uuid,
                state: true,
                success(res) {
                  console.log("notifyBLECharacteristicValueChange success", res);
                },
              });
            }
          }
        },
        fail(res) {
          console.error("getBLEDeviceCharacteristics", res);
        },
      });
      // 操作之前先监听，保证第一时间获取数据
      wx.onBLECharacteristicValueChange(characteristic => {
        // 收到的信息为ArrayBuffer类型，可根据自己的需要转换 可发送给父组件用来回显
        // console.log("收到原始的数据", characteristic, characteristic.value);
        this.handleReceiveMsg(characteristic);
      });
    },
    /* 向蓝牙低功耗设备特征值中写入二进制数据 */
    writeBLECharacteristicValue(command) {
      const buffer = new ArrayBuffer(command.length)
      const dataView = new DataView(buffer)
      for (let i = 0; i < command.length; i++) {
        dataView.setUint8(i, command.charCodeAt(i))
      }
      // console.log("发送数据给蓝牙", "原始字符串", command, "转换arrayBuffer", buffer);
      console.log("发送数据给蓝牙", command);
      wx.writeBLECharacteristicValue({
        deviceId: this.data.characteristic.deviceId,
        serviceId: this.data.characteristic.serviceId, // 微信文档上是错误的
        characteristicId: this.data.characteristic.characteristicId,
        value: buffer, // 只能发送arrayBuffer类型数据
        success(res) {
          console.log("消息发送成功", res.errMsg, command);
        },
        fail(e) {
          console.log("发送消息失败", e);
          if (e.errCode == '10006') {
            wx.showToast({
              title: "请连接蓝牙后进行操作",
              icon: "none"
            });
          } else {
            // wx.showToast({
            //   title: "发送消息失败,错误信息: " + e.errMsg,
            //   icon: "none"
            // });
          }
        },
      });
    },
    closeBluetoothAdapter() {
      console.log("关闭蓝牙模块");
      wx.closeBluetoothAdapter();
      this._discoveryStarted = false;
    },
    handleReceiveMsg(res) {
      let data = res.value;
      // 统一转换为Uint8Array[1,5](@ref)
      if (data instanceof ArrayBuffer) {
        data = new Uint8Array(data);
      }
      try {
        const received = decodeURIComponent(escape(String.fromCharCode(...data)));
        if (received.endsWith('@')) {
          const [cmd, ...params] = received.slice(0, -1).split(';');
          // console.log('params', params);
          //把数据发送给首页渲染
          this.renderPageFn(cmd, params);
        } else if (received.includes('RED:01')) {
          const [cmd, ...params] = received.slice(0, -1).split(';');
          this.renderPageFn(cmd, params);
        }
      } catch (error) {
        // console.log('不能解析');
      }
    },
    renderPageFn(cmd, params) {
      console.log('cmd', cmd, 'params', params);
      //设备主页电量等信息
      if (cmd == "RED:01") {
        // 状态映射配置
        let batteryDesc = null;
        const [battery, chargeStatus, duration, posture, heights] = params;
        if (battery == '9A') {
          batteryDesc = '100';
        } else {
          batteryDesc = battery;
        }
        // 充电状态解析
        let chargeStatusDesc = null;
        if (chargeStatus == 0) {
          chargeStatusDesc = '未充电'
        } else if (chargeStatus == 1) {
          chargeStatusDesc = '充电中'
        } else if (chargeStatus == 1) {
          chargeStatusDesc = '已充满'
        }
        let postureDesc = null;
        if (posture == 1) {
          postureDesc = '仰卧'
        } else if (posture == 2) {
          postureDesc = '侧卧'
        } else if (posture == 3) {
          postureDesc = '已离枕'
        }
        let durationDesc = parseInt(duration.substring(1));
        let homeList = {
          battery: batteryDesc, // 16进制转10进制
          chargeStatus: chargeStatusDesc,
          duration: durationDesc,
          posture: postureDesc,
          heights: heights.match(/.{2}/g).map(h => parseInt(h))
        };
        const child = this.selectComponent('#home');
        if (child) {
          child.init(cmd, homeList);
        }
      }
      if (cmd == 'RED:05') {
        const [status, qnStatus, headHeight, jHeight] = params;
      }
      //睡眠分布 1 的数据
      if (cmd == 'RED:02') {
        const child = this.selectComponent('#sleep')
        if (child) {
          child.init(cmd, params);
        }
      }
      //睡眠分布 2 的数据
      if (cmd == 'RED:03') {
        const child = this.selectComponent('#sleep')
        if (child) {
          child.init(cmd, params);
        }
      }
      // 未检测到仰卧
      // if (cmd == 'SET:00') {
      //   // 未检测到您的仰卧数据，请仰卧，并保持5秒
      //   this.setData({
      //     studyType: true,
      //     studyCon: '未检测到您的仰卧数据，请仰卧，并保持5秒'
      //   })
      // }
      //未检测到侧卧
      // if (cmd == 'SET:03') {
      //   // 未检测到您的仰卧数据，请仰卧，并保持5秒
      //   this.setData({
      //     studyType: true,
      //     studyCon: '未检测到您的侧卧数据，请侧卧，并保持5秒'
      //   })
      // }
      //检测到仰卧,把数据传给学习睡姿页面
      if (cmd == 'SET:01') {
        // 检测到仰卧
        if (params[0] == '01') {
          this.writeBLECharacteristicValue("SET:02;@");
        }
        //检测到侧卧
        if (params[0] == '02') {
          this.writeBLECharacteristicValue("SET:03;@");
        }
        if (params[0] == '03') {
          // 未检测到您的仰卧数据，请仰卧，并保持5秒
          this.setData({
            studyType: true,
            studyCon: '未检测到您的侧卧数据，请侧卧，并保持5秒'
          })
        }
      }
      //检测到侧卧,把数据传给学习睡姿页面
      if (cmd == 'SET:02') {
        if (params[0] == '01' && params[1] == 'OK') {
          let child = this.selectComponent('#pillow');
          if (child) {
            let obj = {
              cmd, params
            }
            child.studyChildFn(obj);
          }
        }
      }
      if (cmd == 'SET:03') {
        if (params[0] == '01' && params[1] == 'OK') {
          let child = this.selectComponent('#pillow');
          if (child) {
            let obj = {
              cmd, params
            }
            child.studyChildFn(obj);
          }
        }
        if (params[0] == '02' && params[1] == 'OK') {
          let child = this.selectComponent('#pillow');
          if (child) {
            child.studyChildFn(cmd, params);
          }
        }
      }
      //科学计算高度完成
      if (cmd == 'SET:06;OK') {
        wx.showToast({
          title: '设置枕高成功',
          icon: "none"
        });
      }
      //仰卧高度完成
      if (cmd == 'SET:07;OK') {
        wx.showToast({
          title: '设置仰卧成功',
          icon: "none"
        });
      }
      //计算侧卧枕高
      if (cmd == 'SET:08;OK') {
        wx.showToast({
          title: '设置侧卧成功',
          icon: "none"
        });
      }
    },
    //改变蓝牙连接
    changeBluetooth(item) {
      let detail = item.detail;
      if (!detail.status) {
        this.setData({
          deviceId: detail.deviceId,
        }, () => {
          this.closeBLEConnection();
        })
      } else {
        this.createBLEConnection(detail);
      }
    },
    //枕头设置学习睡姿
    studyFn(setCon) {
      this.writeBLECharacteristicValue(setCon.detail.detail);
    },
    //科学计算高度
    setMeasureFn(setCon) {
      let {
        detail
      } = setCon.detail;
      this.writeBLECharacteristicValue(detail);
    },
    onChange(e) {
      const {
        value
      } = e.currentTarget.dataset;
      if (value == 'myProfile') {
        this.setData({
          value,
        })
        return
      }
      const {
        list,
        iconMap
      } = this.data;
      // 只更新图标，不更新整个 list
      const newList = list.map(item => ({
        ...item,
        icon: iconMap[value][item.value],
      }));
      this.setData({
        list: newList,
        value,
      }, () => {
        if (value == 'home') {
          this.writeBLECharacteristicValue('RED:01;@');
        }
        if (value == 'pillow') {
          const child = this.selectComponent('#pillow')
          if (child) {
            child.init();
          }
        }
        if (value == 'sleep') {
          this.writeBLECharacteristicValue('RED:02;@');
        }
      });
    },
  },
});